/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package service;

import com.openbrew.openbrewrf.Administration;
import com.openbrew.openbrewrf.DiscountCode;
import com.openbrew.openbrewrf.InvSalesLines;
import com.openbrew.openbrewrf.Sales;
import com.openbrew.openbrewrf.SalesOrder;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;
import pdf.SOPDFCreator;
import tools.InventoryModifiers;
import tools.SaleTools;
import view.CreateSimpleSalesOrderView;
import view.SimpleSalesOrderView;

/**
 *
 * @author chapmand
 */
@Stateless
@Path("com.openbrew.openbrewrf.salesorder")
public class SalesOrderFacadeREST extends AbstractFacade<SalesOrder> {
    @PersistenceContext(unitName = "com.openBrew_openBrewRF_war_1.0PU")
    private EntityManager em;

    public SalesOrderFacadeREST() {
        super(SalesOrder.class);
    }

    @POST
    @Override
    @WebMethod(operationName = "create")
    @Consumes({"application/xml", "application/json"})
    public SalesOrder create(@WebParam(name = "salesorder") SalesOrder entity) {
        entity = super.create(entity);
        return entity;
    }

    @POST
    @Path("createTriggerWithAllocation")
    @WebMethod(operationName = "create")
    @Consumes({"application/xml", "application/json"})
    public SalesOrder createTriggerWA(@WebParam(name = "salesorder") SalesOrder entity) {
        final SaleTools st = new SaleTools();
        final SalesOrder newSO = st.doSaleOrderInsertionActions(em, entity, true);
        if(newSO != null){
            return super.create(newSO);
        } 
        return null;
    }

    @POST
    @Path("createTriggerWithoutAllocation")
    @WebMethod(operationName = "create")
    @Consumes({"application/xml", "application/json"})
    public SalesOrder createTriggerWAO(@WebParam(name = "salesorder") SalesOrder entity) {
        final SaleTools st = new SaleTools();
        final SalesOrder newSO = st.doSaleOrderInsertionActions(em, entity, false);
        if(newSO != null){
            return super.create(newSO);
        } 
        return null;
    }

    @PUT
    @Override
    @Consumes({"application/xml", "application/json"})
    public void edit(SalesOrder entity) {
        final InventoryModifiers im = new InventoryModifiers();
        im.doSalesOrderLineDeletionCheck(em, entity);
        final DiscountCode noDiscount = getNoDiscount(em);
        if(entity.getSalesCollection()!=null){
            for(Sales sale : entity.getSalesCollection()){
                im.doSaleLineCheck(em, sale);
                if(sale.getSDisc() == null){
                    sale.setSDisc(noDiscount);
                }
            }
        }
        if(entity.getInvSalesLinesCollection()!=null){
            for(InvSalesLines sale : entity.getInvSalesLinesCollection()){
                im.doInvSaleLineCheck(em, sale);
                if(sale.getInvSaleDisc()==null){
                    sale.setInvSaleDisc(noDiscount);
                }
            }
        }
        super.edit(entity);
    }
    
    private DiscountCode getNoDiscount(final EntityManager en){
        TypedQuery<DiscountCode> query = en.createQuery(
            "SELECT d FROM DiscountCode d WHERE d.discID='1'", DiscountCode.class);
        return query.getSingleResult();
    }

    @DELETE
    @Path("{id}")
    public void remove(@PathParam("id") Integer id) {
        super.remove(super.find(id));
    }

    @GET
    @Path("{id}")
    @Produces({"application/xml", "application/json"})
    public SalesOrder find(@PathParam("id") Integer id) {
        return super.find(id);
    }

    @GET
    @Path("{id}/so_pdf")
    @Produces({"application/pdf"})
    public StreamingOutput findHeaderImg(@PathParam("id") Integer id) {
        final SalesOrder so = super.find(id);
        return new StreamingOutput() {
            @Override
            public void write(OutputStream output) throws IOException, WebApplicationException {
                try {
                    final Administration admin = getAdmin(em);
                    final SOPDFCreator sopdf = new SOPDFCreator();
                    CreateSimpleSalesOrderView createView = new CreateSimpleSalesOrderView();
                    final SimpleSalesOrderView simpleSalesOrderView = createView.getSalesOrderString(so, admin);

                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    sopdf.createPDF(outputStream, so, simpleSalesOrderView, admin);
                    byte[] bytes = outputStream.toByteArray();
                    output.write(bytes);
                } catch (IOException e) {
                    throw new WebApplicationException(e);
                }
            }
        };
    }
    
    /***************************************************************************
     * Database modification functions.
     **************************************************************************/
    private Administration getAdmin(final EntityManager en){
        TypedQuery<Administration> query = en.createQuery(
            "SELECT a FROM Administration a WHERE a.aNum = '1'", Administration.class);
        Administration admin = query.getSingleResult();
        return admin;
    }

    @GET
    @Override
    @Produces({"application/xml", "application/json"})
    public List<SalesOrder> findAll() {
        return super.findAll();
    }
    
    @GET
    @Path("getGroup/{from}/{to}")
    @Produces({"application/xml", "application/json"})
    public List<SalesOrder> getGroup(@PathParam("from") Integer from, @PathParam("to") Integer to) {
        TypedQuery<SalesOrder> query = em.createQuery(
                "SELECT so FROM SalesOrder so WHERE so.sOId >= ?1 AND so.sOId <= ?2", SalesOrder.class);
        query.setParameter(1, from);
        query.setParameter(2, to);
        List<SalesOrder> sos = query.getResultList();
        return sos;
    }
    
    @GET
    @Path("{from}/{to}")
    @Produces({"application/xml", "application/json"})
    public List<SalesOrder> findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) {
        return super.findRange(new int[]{from, to});
    }

    @GET
    @Path("namedQueryRange/{from}/{to}/{str}/{id}")
    @Produces({"application/xml", "application/json"})
    public List<SalesOrder> findNamedQueryRange(@PathParam("from") Integer from
            , @PathParam("to") Integer to, @PathParam("str") String str
            , @PathParam("id") Integer id) {
        return super.findNamedQueryRange(new int[]{from, to}, str, id);
    }

    @GET
    @Path("namedQueryCount/{str}/{id}")
    @Produces("text/plain")
    public String namedQueryCount(@PathParam("str") String str
            , @PathParam("id") Integer id) {
        return String.valueOf(super.namedQueryCount(str, id, "cId"));
    }

    @GET
    @Path("count")
    @Produces("text/plain")
    public String countREST() {
        return String.valueOf(super.count());
    }

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }
    
}
